﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.Globalization;

namespace SmartMathLibrary.Management.Performance
{
    /// <summary>
    /// Defines the significant properties of a video controller.
    /// </summary>
    public enum VideoControllerProperty
    {
        /// <summary>
        /// The AdapterCompatibility property of the video controller.
        /// </summary>
        AdapterCompatibility,
        /// <summary>
        /// The AdapterDACType property of the video controller.
        /// </summary>
        AdapterDACType,
        /// <summary>
        /// The AdapterRAM property of the video controller.
        /// </summary>
        AdapterRAM,
        /// <summary>
        /// The Availability property of the video controller.
        /// </summary>
        Availability,
        /// <summary>
        /// The Caption property of the video controller.
        /// </summary>
        Caption,
        /// <summary>
        /// The ColorTableEntries property of the video controller.
        /// </summary>
        ColorTableEntries,
        /// <summary>
        /// The ConfigManagerErrorCode property of the video controller.
        /// </summary>
        ConfigManagerErrorCode,
        /// <summary>
        /// The ConfigManagerUserConfig property of the video controller.
        /// </summary>
        ConfigManagerUserConfig,
        /// <summary>
        /// The CreationClassName property of the video controller.
        /// </summary>
        CreationClassName,
        /// <summary>
        /// The CurrentBitsPerPixel property of the video controller.
        /// </summary>
        CurrentBitsPerPixel,
        /// <summary>
        /// The CurrentHorizontalResolution property of the video controller.
        /// </summary>
        CurrentHorizontalResolution,
        /// <summary>
        /// The CurrentNumberOfColors property of the video controller.
        /// </summary>
        CurrentNumberOfColors,
        /// <summary>
        /// The CurrentNumberOfColumns property of the video controller.
        /// </summary>
        CurrentNumberOfColumns,
        /// <summary>
        /// The CurrentNumberOfRows property of the video controller.
        /// </summary>
        CurrentNumberOfRows,
        /// <summary>
        /// The CurrentRefreshRate property of the video controller.
        /// </summary>
        CurrentRefreshRate,
        /// <summary>
        /// The CurrentScanMode property of the video controller.
        /// </summary>
        CurrentScanMode,
        /// <summary>
        /// The CurrentVerticalResolution property of the video controller.
        /// </summary>
        CurrentVerticalResolution,
        /// <summary>
        /// The Description property of the video controller.
        /// </summary>
        Description,
        /// <summary>
        /// The DeviceID property of the video controller.
        /// </summary>
        DeviceID,
        /// <summary>
        /// The DeviceSpecificPens property of the video controller.
        /// </summary>
        DeviceSpecificPens,
        /// <summary>
        /// The DitherType property of the video controller.
        /// </summary>
        DitherType,
        /// <summary>
        /// The DriverVersion property of the video controller.
        /// </summary>
        DriverVersion,
        /// <summary>
        /// The InstalledDisplayDrivers property of the video controller.
        /// </summary>
        InstalledDisplayDrivers,
        /// <summary>
        /// The MaxMemorySupported property of the video controller.
        /// </summary>
        MaxMemorySupported,
        /// <summary>
        /// The MaxNumberControlled property of the video controller.
        /// </summary>
        MaxNumberControlled,
        /// <summary>
        /// The MaxRefreshRate property of the video controller.
        /// </summary>
        MaxRefreshRate,
        /// <summary>
        /// The  property of the video controller.
        /// </summary>
        MinRefreshRate,
        /// <summary>
        /// The Monochrome property of the video controller.
        /// </summary>
        Monochrome,
        /// <summary>
        /// The Name property of the video controller.
        /// </summary>
        Name,
        /// <summary>
        /// The NumberOfColorPlanes property of the video controller.
        /// </summary>
        NumberOfColorPlanes,
        /// <summary>
        /// The NumberOfVideoPages property of the video controller.
        /// </summary>
        NumberOfVideoPages,
        /// <summary>
        /// The PNPDeviceID property of the video controller.
        /// </summary>
        PNPDeviceID,
        /// <summary>
        /// The PowerManagementSupported property of the video controller.
        /// </summary>
        PowerManagementSupported,
        /// <summary>
        /// The ProtocolSupported property of the video controller.
        /// </summary>
        ProtocolSupported,
        /// <summary>
        /// The ReservedSystemPaletteEntries property of the video controller.
        /// </summary>
        ReservedSystemPaletteEntries,
        /// <summary>
        /// The SpecificationVersion property of the video controller.
        /// </summary>
        SpecificationVersion,
        /// <summary>
        /// The Status property of the video controller.
        /// </summary>
        Status,
        /// <summary>
        /// The StatusInfo property of the video controller.
        /// </summary>
        StatusInfo,
        /// <summary>
        /// The SystemCreationClassName property of the video controller.
        /// </summary>
        SystemCreationClassName,
        /// <summary>
        /// The SystemName property of the video controller.
        /// </summary>
        SystemName,
        /// <summary>
        /// The SystemPaletteEntries property of the video controller.
        /// </summary>
        SystemPaletteEntries,
        /// <summary>
        /// The VideoArchitecture property of the video controller.
        /// </summary>
        VideoArchitecture,
        /// <summary>
        /// The VideoMemoryType property of the video controller.
        /// </summary>
        VideoMemoryType,
        /// <summary>
        /// The VideoMode property of the video controller.
        /// </summary>
        VideoMode,
        /// <summary>
        /// The VideoModeDescription property of the video controller.
        /// </summary>
        VideoModeDescription,
        /// <summary>
        /// The VideoProcessor property of the video controller.
        /// </summary>
        VideoProcessor
    }

    /// <summary>
    /// This class provides a gateway to information of the current video controllers,
    /// which includes the running system.
    /// </summary>
    [Serializable]
    public static class VideoControllerInformationProvider
    {
        /// <summary>
        /// Collects the significant information of the current video controllers.
        /// </summary>
        /// <returns>The significant information of the current video controllers</returns>
        public static VideoControllerInformation[] CollectInformations()
        {
            int i = 0;
            ManagementObjectSearcher searcher = new ManagementObjectSearcher
                ("root\\CIMV2", "SELECT * FROM Win32_VideoController");

            VideoControllerInformation[] informations = new
                VideoControllerInformation[searcher.Get().Count];

            try
            {
                foreach (ManagementObject queryObj in searcher.Get())
                {
                    informations[i] = new VideoControllerInformation();

                    if (queryObj["AdapterCompatibility"] != null)
                    {
                        informations[i].AdapterCompatibility = queryObj["AdapterCompatibility"].ToString();
                    }

                    if (queryObj["AdapterDACType"] != null)
                    {
                        informations[i].AdapterDACType = queryObj["AdapterDACType"].ToString();
                    }

                    if (queryObj["AdapterRAM"] != null)
                    {
                        informations[i].AdapterRAM = UInt32.Parse(queryObj["AdapterRAM"].ToString(),
                                                                  CultureInfo.CurrentCulture);
                    }

                    if (queryObj["Availability"] != null)
                    {
                        informations[i].Availability = UInt16.Parse(queryObj["Availability"].ToString(),
                                                                    CultureInfo.CurrentCulture);
                    }

                    if (queryObj["Caption"] != null)
                    {
                        informations[i].Caption = queryObj["Caption"].ToString();
                    }

                    if (queryObj["ColorTableEntries"] != null)
                    {
                        informations[i].ColorTableEntries = UInt32.Parse(queryObj["ColorTableEntries"].ToString(),
                                                                         CultureInfo.CurrentCulture);
                    }

                    if (queryObj["ConfigManagerErrorCode"] != null)
                    {
                        informations[i].ConfigManagerErrorCode =
                            UInt32.Parse(queryObj["ConfigManagerErrorCode"].ToString(), CultureInfo.CurrentCulture);
                    }

                    if (queryObj["ConfigManagerUserConfig"] != null)
                    {
                        informations[i].ConfigManagerUserConfig =
                            Boolean.Parse(queryObj["ConfigManagerUserConfig"].ToString());
                    }

                    if (queryObj["CreationClassName"] != null)
                    {
                        informations[i].CreationClassName = queryObj["CreationClassName"].ToString();
                    }

                    if (queryObj["CurrentBitsPerPixel"] != null)
                    {
                        informations[i].CurrentBitsPerPixel = UInt32.Parse(queryObj["CurrentBitsPerPixel"].ToString(),
                                                                           CultureInfo.CurrentCulture);
                    }

                    if (queryObj["CurrentHorizontalResolution"] != null)
                    {
                        informations[i].CurrentHorizontalResolution =
                            UInt32.Parse(queryObj["CurrentHorizontalResolution"].ToString(), CultureInfo.CurrentCulture);
                    }

                    if (queryObj["CurrentNumberOfColors"] != null)
                    {
                        informations[i].CurrentNumberOfColors =
                            UInt64.Parse(queryObj["CurrentNumberOfColors"].ToString(), CultureInfo.CurrentCulture);
                    }

                    if (queryObj["CurrentNumberOfColumns"] != null)
                    {
                        informations[i].CurrentNumberOfColumns =
                            UInt32.Parse(queryObj["CurrentNumberOfColumns"].ToString(), CultureInfo.CurrentCulture);
                    }

                    if (queryObj["CurrentNumberOfRows"] != null)
                    {
                        informations[i].CurrentNumberOfRows = UInt32.Parse(queryObj["CurrentNumberOfRows"].ToString(),
                                                                           CultureInfo.CurrentCulture);
                    }

                    if (queryObj["CurrentRefreshRate"] != null)
                    {
                        informations[i].CurrentRefreshRate = UInt32.Parse(queryObj["CurrentRefreshRate"].ToString(),
                                                                          CultureInfo.CurrentCulture);
                    }

                    if (queryObj["CurrentScanMode"] != null)
                    {
                        informations[i].CurrentScanMode = UInt16.Parse(queryObj["CurrentScanMode"].ToString(),
                                                                       CultureInfo.CurrentCulture);
                    }

                    if (queryObj["CurrentVerticalResolution"] != null)
                    {
                        informations[i].CurrentVerticalResolution =
                            UInt32.Parse(queryObj["CurrentVerticalResolution"].ToString(), CultureInfo.CurrentCulture);
                    }

                    if (queryObj["Description"] != null)
                    {
                        informations[i].Description = queryObj["Description"].ToString();
                    }

                    if (queryObj["DeviceID"] != null)
                    {
                        informations[i].DeviceID = queryObj["DeviceID"].ToString();
                    }

                    if (queryObj["DeviceSpecificPens"] != null)
                    {
                        informations[i].DeviceSpecificPens = UInt32.Parse(queryObj["DeviceSpecificPens"].ToString(),
                                                                          CultureInfo.CurrentCulture);
                    }

                    if (queryObj["DitherType"] != null)
                    {
                        informations[i].DitherType = UInt32.Parse(queryObj["DitherType"].ToString(),
                                                                  CultureInfo.CurrentCulture);
                    }

                    if (queryObj["DriverVersion"] != null)
                    {
                        informations[i].DriverVersion = queryObj["DriverVersion"].ToString();
                    }

                    if (queryObj["InstalledDisplayDrivers"] != null)
                    {
                        informations[i].InstalledDisplayDrivers = queryObj["InstalledDisplayDrivers"].ToString();
                    }

                    if (queryObj["MaxMemorySupported"] != null)
                    {
                        informations[i].MaxMemorySupported = UInt32.Parse(queryObj["MaxMemorySupported"].ToString(),
                                                                          CultureInfo.CurrentCulture);
                    }

                    if (queryObj["MaxNumberControlled"] != null)
                    {
                        informations[i].MaxNumberControlled = UInt32.Parse(queryObj["MaxNumberControlled"].ToString(),
                                                                           CultureInfo.CurrentCulture);
                    }

                    if (queryObj["MaxRefreshRate"] != null)
                    {
                        informations[i].MaxRefreshRate = UInt32.Parse(queryObj["MaxRefreshRate"].ToString(),
                                                                      CultureInfo.CurrentCulture);
                    }

                    if (queryObj["MinRefreshRate"] != null)
                    {
                        informations[i].MinRefreshRate = UInt32.Parse(queryObj["MinRefreshRate"].ToString(),
                                                                      CultureInfo.CurrentCulture);
                    }

                    if (queryObj["Monochrome"] != null)
                    {
                        informations[i].Monochrome = Boolean.Parse(queryObj["Monochrome"].ToString());
                    }

                    if (queryObj["Name"] != null)
                    {
                        informations[i].Name = queryObj["Name"].ToString();
                    }

                    if (queryObj["NumberOfColorPlanes"] != null)
                    {
                        informations[i].NumberOfColorPlanes = UInt16.Parse(queryObj["NumberOfColorPlanes"].ToString(),
                                                                           CultureInfo.CurrentCulture);
                    }

                    if (queryObj["NumberOfVideoPages"] != null)
                    {
                        informations[i].NumberOfVideoPages = UInt32.Parse(queryObj["NumberOfVideoPages"].ToString(),
                                                                          CultureInfo.CurrentCulture);
                    }

                    if (queryObj["PNPDeviceID"] != null)
                    {
                        informations[i].PNPDeviceID = queryObj["PNPDeviceID"].ToString();
                    }

                    if (queryObj["PowerManagementSupported"] != null)
                    {
                        informations[i].PowerManagementSupported =
                            Boolean.Parse(queryObj["PowerManagementSupported"].ToString());
                    }

                    if (queryObj["ProtocolSupported"] != null)
                    {
                        informations[i].ProtocolSupported = UInt16.Parse(queryObj["ProtocolSupported"].ToString(),
                                                                         CultureInfo.CurrentCulture);
                    }

                    if (queryObj["ReservedSystemPaletteEntries"] != null)
                    {
                        informations[i].ReservedSystemPaletteEntries =
                            UInt32.Parse(queryObj["ReservedSystemPaletteEntries"].ToString(), CultureInfo.CurrentCulture);
                    }

                    if (queryObj["SpecificationVersion"] != null)
                    {
                        informations[i].SpecificationVersion = UInt32.Parse(
                            queryObj["SpecificationVersion"].ToString(), CultureInfo.CurrentCulture);
                    }

                    if (queryObj["Status"] != null)
                    {
                        informations[i].Status = queryObj["Status"].ToString();
                    }

                    if (queryObj["StatusInfo"] != null)
                    {
                        informations[i].StatusInfo = UInt16.Parse(queryObj["StatusInfo"].ToString(),
                                                                  CultureInfo.CurrentCulture);
                    }

                    if (queryObj["SystemCreationClassName"] != null)
                    {
                        informations[i].SystemCreationClassName = queryObj["SystemCreationClassName"].ToString();
                    }

                    if (queryObj["SystemName"] != null)
                    {
                        informations[i].SystemName = queryObj["SystemName"].ToString();
                    }

                    if (queryObj["SystemPaletteEntries"] != null)
                    {
                        informations[i].SystemPaletteEntries = UInt32.Parse(
                            queryObj["SystemPaletteEntries"].ToString(), CultureInfo.CurrentCulture);
                    }

                    if (queryObj["VideoArchitecture"] != null)
                    {
                        informations[i].VideoArchitecture = UInt16.Parse(queryObj["VideoArchitecture"].ToString(),
                                                                         CultureInfo.CurrentCulture);
                    }

                    if (queryObj["VideoMemoryType"] != null)
                    {
                        informations[i].VideoMemoryType = UInt16.Parse(queryObj["VideoMemoryType"].ToString(),
                                                                       CultureInfo.CurrentCulture);
                    }

                    if (queryObj["VideoMode"] != null)
                    {
                        informations[i].VideoMode = UInt16.Parse(queryObj["VideoMode"].ToString(),
                                                                 CultureInfo.CurrentCulture);
                    }

                    if (queryObj["VideoProcessor"] != null)
                    {
                        informations[i].VideoModeDescription = queryObj["VideoProcessor"].ToString();
                    }

                    if (queryObj["VideoProcessor"] != null)
                    {
                        informations[i].VideoProcessor = queryObj["VideoProcessor"].ToString();
                    }

                    i++;
                }
            }
            catch
            {
                throw new InformationNotFoundException("Cannot find the specified information.");
            }

            return informations;
        }

        /// <summary>
        /// Collects a special information of the processor.
        /// </summary>
        /// <param name="property">The special information property.</param>
        /// <returns>The special information of the processor.</returns>
        public static Object[] CollectSpecialInformation(VideoControllerProperty property)
        {
            int i = 0;
            ManagementObjectSearcher searcher = new ManagementObjectSearcher
                ("root\\CIMV2", "SELECT * FROM Win32_VideoController");
            Object[] informations = new Object[searcher.Get().Count];

            try
            {
                foreach (ManagementObject queryObj in searcher.Get())
                {
                    informations[i] = queryObj[property.ToString()];
                    i++;
                }
            }
            catch
            {
                throw new InformationNotFoundException("Cannot find the specified information.");
            }

            return informations;
        }
    }
}